package device

import (
	"context"
	"sync"
	"time"

	"device-admin/config/mysql"
	"device-admin/internal/app/grpc/client"
	"device-admin/internal/app/grpc/protoc/sale_adminc"
	"device-admin/internal/models"

	db_sharding "192.168.1.75/go-pkg/db-sharding"
	"192.168.1.75/go-pkg/logx"
	"github.com/golang-module/carbon/v2"
	"github.com/samber/lo"
)

type HeatMapRobotT struct {
	RobotID            string `json:"robot_id" gorm:"column:robot_id"`
	IdentificationCode string `json:"identification_code" gorm:"column:identification_code"`
}

// UpdateHeatMapConsumer 热力图任务消费
func UpdateHeatMapConsumer() error {
	logx.Info(context.Background(), "crond UpdateHeatMap")
	// 昨日时间戳
	yesterday := time.Unix(carbon.Now().Yesterday().EndOfDay().Timestamp(), 0).Format("2006-01-02")
	// 所有的设备
	var Robots []HeatMapRobotT
	// 获取所有的设备
	dbs := db_sharding.GetDB(
		context.Background(),
		mysql.NewDB(),
		models.DeviceHeatMapTpl{},
		carbon.Now().Yesterday().StartOfDay().Timestamp(),
		carbon.Now().Yesterday().EndOfDay().Timestamp(),
	)
	dbs.QueryDB.
		Joins("LEFT JOIN device ON device.robot_id = device_heat_map.robot_id").
		Select("device_heat_map.robot_id", "device.identification_code").
		Where("created_date = ?", yesterday).
		Group("robot_id").
		Find(&Robots)
	t0 := carbon.Now().Yesterday().StartOfDay().SubDay().Timestamp() // 昨日结束时间
	// 进行分块处理，每次并行处理5台设备
	chunkRobots := lo.Chunk(Robots, 5)
	for _, Robots := range chunkRobots {
		var wg sync.WaitGroup
		wg.Add(len(Robots))
		for _, record := range Robots {
			// 先获取每个小数的数据
			// 再获取每五分钟的数据，如果为空，则取一个小时的平均
			go func(record HeatMapRobotT) {
				defer func() {
					wg.Done()
				}()
				for h := int64(0); h < 24*2; h++ {
					// 跳过非营运时间段，默认营运时间段为10:00-22:00
					if !(h%24 >= 10 && h%24 < 22) {
						continue
					}
					var (
						hourData   *sale_adminc.RobotHeatMapRsp
						minuteData *sale_adminc.RobotHeatMapRsp
					)
					// 获取分表
					dbs := db_sharding.GetDB(
						context.Background(),
						mysql.NewDB(),
						models.DeviceHeatMapTpl{},
						t0,
						t0+h,
					)
					// 获取小数数据
					{
						// 时间条件
						t1 := time.Unix(t0+h*3600, 0).Format("2006-01-02 15:04:05")
						t2 := time.Unix(t0+(h+1)*3600, 0).Format("2006-01-02 15:04:05")
						// 请求
						cli, err := client.GetSaleAdminClient()
						if err != nil {
							logx.Error(context.Background(), "UpdateHeatMapConsumer", logx.Err(err))
							continue
						}
						rsp, err := cli.GetHeatMapInfo(context.Background(), &sale_adminc.RobotHeatMapReq{
							IdentificationCode: record.IdentificationCode,
							StartTime:          t1,
							EndTime:            t2,
						})
						if err != nil {
							logx.Error(context.Background(), "UpdateHeatMapConsumer", logx.Err(err))
							continue
						}
						if len(rsp.List) > 0 {
							hourData = rsp.List[0]
						}
					}
					// 获取分钟数据
					for s := t0 + h*3600; s < t0+(h+1)*3600; s += 300 {
						{
							createdMinute := time.Unix(s, 0).Format("2006-01-02 15:04")
							t1 := time.Unix(s, 0).Format("2006-01-02 15:04:05")
							t2 := time.Unix(s+300, 0).Format("2006-01-02 15:04:05")
							cli, err := client.GetSaleAdminClient()
							if err != nil {
								logx.Error(context.Background(), "UpdateHeatMapConsumer", logx.Err(err))
								continue
							}
							rsp, err := cli.GetHeatMapInfo(context.Background(), &sale_adminc.RobotHeatMapReq{
								IdentificationCode: record.IdentificationCode,
								StartTime:          t1,
								EndTime:            t2,
							})
							if err != nil {
								logx.Error(context.Background(), "UpdateHeatMapConsumer", logx.Err(err))
								continue
							}
							if len(rsp.List) > 0 {
								minuteData = rsp.List[0]
							}
							// 分钟数据
							{
								if minuteData == nil && hourData != nil {
									minuteData = &sale_adminc.RobotHeatMapRsp{}
									minuteData.StartOrderCount = hourData.StartOrderCount * 100 / 12
									minuteData.SuccessOrderCount = hourData.SuccessOrderCount * 100 / 12
									minuteData.FaceCount = hourData.FaceCount / 12
									minuteData.FaceCount0 = hourData.FaceCount0 / 12
									minuteData.FaceCount1 = hourData.FaceCount1 / 12
									minuteData.FaceCount2 = hourData.FaceCount2 / 12
								}
							}
							// 更新至数据库
							if minuteData != nil {
								dbs.UpdateDB.Where("robot_id = ?", record.RobotID).
									Where("created_minute = ?", createdMinute).
									Updates(&models.DeviceHeatMap{
										CreatedOrderNumber: minuteData.StartOrderCount,
										PaidOrderNumber:    minuteData.SuccessOrderCount,
										FaceCount:          minuteData.FaceCount,
										FaceCountFront:     minuteData.FaceCount0,
										FaceCountLeft:      minuteData.FaceCount1,
										FaceCountRight:     minuteData.FaceCount2,
									})
							}
						}
					}
				}
			}(record)
		}
		wg.Wait()
	}
	return nil
}
